{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
      "  from ._conv import register_converters as _register_converters\n",
      "/usr/local/lib/python3.5/dist-packages/dicom/__init__.py:53: UserWarning: \n",
      "This code is using an older version of pydicom, which is no longer \n",
      "maintained as of Jan 2017.  You can access the new pydicom features and API \n",
      "by installing `pydicom` from PyPI.\n",
      "See 'Transitioning to pydicom 1.x' section at pydicom.readthedocs.org \n",
      "for more information.\n",
      "\n",
      "  warnings.warn(msg)\n",
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "import sys\n",
    "sys.path.append('..')\n",
    "import radio\n",
    "import radio.annotation\n",
    "import glob\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Reading annotation file"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Submodule **radio.utils** contains **read_nodules** function that accepts path to annotation file as it's first argument:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "annotation_path = '/notebooks/data/CT/npcmr/ct_annotation/08_annotation.txt'\n",
    "dicom_path = '/notebooks/data/CT/npcmr/08/*/*/*/*/*'\n",
    "blosc_path = '/notebooks/ct/npcmr_blosc/*'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>DoctorID</th>\n",
       "      <th>NoduleID</th>\n",
       "      <th>NoduleType</th>\n",
       "      <th>coordX</th>\n",
       "      <th>coordY</th>\n",
       "      <th>coordZ</th>\n",
       "      <th>diameter_mm</th>\n",
       "      <th>seriesid</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>40</th>\n",
       "      <td>002</td>\n",
       "      <td>3a35f11d6f9fe83f3ac5</td>\n",
       "      <td>solid</td>\n",
       "      <td>410.0</td>\n",
       "      <td>274.0</td>\n",
       "      <td>330.0</td>\n",
       "      <td>9.0</td>\n",
       "      <td>AGFA000000061588</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>41</th>\n",
       "      <td>002</td>\n",
       "      <td>8dc2caf414fcea3f4088</td>\n",
       "      <td>semi_solid</td>\n",
       "      <td>144.0</td>\n",
       "      <td>355.0</td>\n",
       "      <td>221.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>AGFA000000061588</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>45</th>\n",
       "      <td>002</td>\n",
       "      <td>08a91259410bcf3fbcba</td>\n",
       "      <td>solid</td>\n",
       "      <td>163.0</td>\n",
       "      <td>152.0</td>\n",
       "      <td>134.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>AGFA000000061588</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>46</th>\n",
       "      <td>002</td>\n",
       "      <td>8cd5580f0c88eb3fa212</td>\n",
       "      <td>semi_solid</td>\n",
       "      <td>159.0</td>\n",
       "      <td>162.0</td>\n",
       "      <td>133.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>AGFA000000061588</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>80</th>\n",
       "      <td>005</td>\n",
       "      <td>3afe3be934dce13f2309</td>\n",
       "      <td>semi_solid</td>\n",
       "      <td>412.0</td>\n",
       "      <td>273.0</td>\n",
       "      <td>330.0</td>\n",
       "      <td>9.0</td>\n",
       "      <td>AGFA000000061588</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>120</th>\n",
       "      <td>010</td>\n",
       "      <td>15fab241d097e43fa45f</td>\n",
       "      <td>solid</td>\n",
       "      <td>410.0</td>\n",
       "      <td>273.0</td>\n",
       "      <td>331.0</td>\n",
       "      <td>9.0</td>\n",
       "      <td>AGFA000000061588</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>122</th>\n",
       "      <td>010</td>\n",
       "      <td>61dae525eaeded3fca52</td>\n",
       "      <td>solid</td>\n",
       "      <td>202.0</td>\n",
       "      <td>165.0</td>\n",
       "      <td>203.0</td>\n",
       "      <td>8.0</td>\n",
       "      <td>AGFA000000061588</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>123</th>\n",
       "      <td>010</td>\n",
       "      <td>0863a9b06ff4c63fe85f</td>\n",
       "      <td>solid</td>\n",
       "      <td>192.0</td>\n",
       "      <td>211.0</td>\n",
       "      <td>195.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>AGFA000000061588</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>124</th>\n",
       "      <td>010</td>\n",
       "      <td>ea4b71c44fcfd13f822e</td>\n",
       "      <td>solid</td>\n",
       "      <td>183.0</td>\n",
       "      <td>325.0</td>\n",
       "      <td>143.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>AGFA000000061588</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>280</th>\n",
       "      <td>008</td>\n",
       "      <td>4a078dc3cf36ef3f8c27</td>\n",
       "      <td>solid</td>\n",
       "      <td>162.0</td>\n",
       "      <td>369.0</td>\n",
       "      <td>365.0</td>\n",
       "      <td>12.0</td>\n",
       "      <td>AGFA000000061613</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    DoctorID              NoduleID  NoduleType  coordX  coordY  coordZ  \\\n",
       "40       002  3a35f11d6f9fe83f3ac5       solid   410.0   274.0   330.0   \n",
       "41       002  8dc2caf414fcea3f4088  semi_solid   144.0   355.0   221.0   \n",
       "45       002  08a91259410bcf3fbcba       solid   163.0   152.0   134.0   \n",
       "46       002  8cd5580f0c88eb3fa212  semi_solid   159.0   162.0   133.0   \n",
       "80       005  3afe3be934dce13f2309  semi_solid   412.0   273.0   330.0   \n",
       "120      010  15fab241d097e43fa45f       solid   410.0   273.0   331.0   \n",
       "122      010  61dae525eaeded3fca52       solid   202.0   165.0   203.0   \n",
       "123      010  0863a9b06ff4c63fe85f       solid   192.0   211.0   195.0   \n",
       "124      010  ea4b71c44fcfd13f822e       solid   183.0   325.0   143.0   \n",
       "280      008  4a078dc3cf36ef3f8c27       solid   162.0   369.0   365.0   \n",
       "\n",
       "     diameter_mm          seriesid  \n",
       "40           9.0  AGFA000000061588  \n",
       "41           5.0  AGFA000000061588  \n",
       "45           5.0  AGFA000000061588  \n",
       "46           4.0  AGFA000000061588  \n",
       "80           9.0  AGFA000000061588  \n",
       "120          9.0  AGFA000000061588  \n",
       "122          8.0  AGFA000000061588  \n",
       "123          5.0  AGFA000000061588  \n",
       "124          5.0  AGFA000000061588  \n",
       "280         12.0  AGFA000000061613  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nodules = radio.annotation.read_nodules(annotation_path)\n",
    "nodules.head(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you need to get information about doctors that annotated each scan you can just use function **read_annotators_info**:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>DoctorID</th>\n",
       "      <th>doctor_000</th>\n",
       "      <th>doctor_001</th>\n",
       "      <th>doctor_002</th>\n",
       "      <th>doctor_003</th>\n",
       "      <th>doctor_004</th>\n",
       "      <th>doctor_005</th>\n",
       "      <th>doctor_006</th>\n",
       "      <th>doctor_007</th>\n",
       "      <th>doctor_008</th>\n",
       "      <th>doctor_009</th>\n",
       "      <th>doctor_010</th>\n",
       "      <th>doctor_011</th>\n",
       "      <th>doctor_012</th>\n",
       "      <th>doctor_013</th>\n",
       "      <th>doctor_014</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>seriesid</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>AGFA000000061588</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>AGFA000000061590</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>AGFA000000061613</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>AGFA000000061820</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>AGFA000000061951</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>AGFA000000062036</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>AGFA000000062311</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>AGFA000000062422</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>AGFA000000062507</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>AGFA000000062562</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "DoctorID          doctor_000  doctor_001  doctor_002  doctor_003  doctor_004  \\\n",
       "seriesid                                                                       \n",
       "AGFA000000061588           0           0           1           0           0   \n",
       "AGFA000000061590           0           0           0           0           0   \n",
       "AGFA000000061613           0           0           0           0           0   \n",
       "AGFA000000061820           0           0           0           0           0   \n",
       "AGFA000000061951           0           1           1           0           0   \n",
       "AGFA000000062036           1           1           0           0           0   \n",
       "AGFA000000062311           0           1           0           0           0   \n",
       "AGFA000000062422           0           0           0           0           0   \n",
       "AGFA000000062507           0           0           0           0           0   \n",
       "AGFA000000062562           0           1           0           0           0   \n",
       "\n",
       "DoctorID          doctor_005  doctor_006  doctor_007  doctor_008  doctor_009  \\\n",
       "seriesid                                                                       \n",
       "AGFA000000061588           1           0           0           0           0   \n",
       "AGFA000000061590           1           0           0           0           1   \n",
       "AGFA000000061613           0           0           0           1           0   \n",
       "AGFA000000061820           0           1           0           0           0   \n",
       "AGFA000000061951           0           0           0           0           0   \n",
       "AGFA000000062036           0           1           0           0           0   \n",
       "AGFA000000062311           0           0           0           1           0   \n",
       "AGFA000000062422           1           0           0           0           0   \n",
       "AGFA000000062507           0           0           1           0           0   \n",
       "AGFA000000062562           1           0           0           0           0   \n",
       "\n",
       "DoctorID          doctor_010  doctor_011  doctor_012  doctor_013  doctor_014  \n",
       "seriesid                                                                      \n",
       "AGFA000000061588           1           0           0           0           0  \n",
       "AGFA000000061590           0           0           1           0           0  \n",
       "AGFA000000061613           0           0           0           1           1  \n",
       "AGFA000000061820           0           1           0           1           0  \n",
       "AGFA000000061951           0           0           0           1           0  \n",
       "AGFA000000062036           0           0           0           0           0  \n",
       "AGFA000000062311           0           0           0           0           1  \n",
       "AGFA000000062422           1           0           0           0           1  \n",
       "AGFA000000062507           1           0           0           1           0  \n",
       "AGFA000000062562           0           0           0           1           0  "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "annotators = radio.annotation.read_annotators_info(annotation_path, annotator_prefix='doctor_')\n",
    "annotators.head(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Each row in **annotators** dataframe corresponds to AccessionNumber and represents those doctors who were annotating corresponding scan."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plotting distribution of nodules among doctors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below you can find code that plots bar chart for number of nodules that were annotated by each doctor:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 504x360 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(7, 5))\n",
    "ax = (\n",
    "    nodules\n",
    "    .set_index('seriesid')\n",
    "    .merge(annotators, left_index=True, right_index=True)\n",
    "    .filter(regex='doctor_\\d{3}', axis=1)\n",
    "    .unstack()\n",
    "    .groupby(level=0)\n",
    "    .sum()\n",
    "    .plot(kind='bar', grid=True)\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can use **assign_nodules_group_index** function to add column *GroupNoduleID* that contains the same values\n",
    "for different overlapping nodules(commonly, that group of overlapping nodules is just annotations from different doctors):"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Note**: before assigning nodules group index and uniting them into group you need to check that **[coordX, coordY, coordZ]** columns contain coordintates in mm. If coordinates provided in pixel scale you can make the following transform:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.5/dist-packages/pandas/core/indexing.py:1020: FutureWarning: \n",
      "Passing list-likes to .loc or [] with any missing label will raise\n",
      "KeyError in the future, you can use .reindex() as an alternative.\n",
      "\n",
      "See the documentation here:\n",
      "http://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate-loc-reindex-listlike\n",
      "  return getattr(section, self.name)[new_key]\n"
     ]
    }
   ],
   "source": [
    "dataset_info = (\n",
    "    radio.annotation.read_dataset_info(blosc_path, index_col=None, fmt='blosc')\n",
    "    .drop_duplicates(subset=['seriesid'])\n",
    "    .set_index('seriesid')\n",
    ")\n",
    "\n",
    "nodules = (\n",
    "    radio.annotation.read_nodules(annotation_path)\n",
    "    .set_index('seriesid')\n",
    "    .assign(coordZ=lambda df: df.loc[:, 'coordZ'] * dataset_info.loc[df.index, 'SpacingZ'] + dataset_info.loc[df.index, 'OriginZ'],\n",
    "            coordY=lambda df: df.loc[:, 'coordY'] * dataset_info.loc[df.index, 'SpacingY'] + dataset_info.loc[df.index, 'OriginY'],\n",
    "            coordX=lambda df: df.loc[:, 'coordX'] * dataset_info.loc[df.index, 'SpacingX'] + dataset_info.loc[df.index, 'OriginX'])\n",
    "    .reset_index()\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you can see, additional information about spacing in dataset's scans is required to do that. It can be easily obtained using **radio.annotation.read_dataset_info** function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "from radio.annotation import assign_nodules_group_index\n",
    "\n",
    "nodules_with_group_index = (\n",
    "    nodules\n",
    "    .set_index(['seriesid', 'NoduleID'])\n",
    "    .groupby(level=0)\n",
    "    .apply(assign_nodules_group_index)\n",
    "    .reset_index()\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>seriesid</th>\n",
       "      <th>NoduleID</th>\n",
       "      <th>DoctorID</th>\n",
       "      <th>NoduleType</th>\n",
       "      <th>coordX</th>\n",
       "      <th>coordY</th>\n",
       "      <th>coordZ</th>\n",
       "      <th>diameter_mm</th>\n",
       "      <th>GroupNoduleID</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>AGFA000000061588</td>\n",
       "      <td>3ccf38f4489fd23fe166</td>\n",
       "      <td>002</td>\n",
       "      <td>solid</td>\n",
       "      <td>105.3718</td>\n",
       "      <td>12.484</td>\n",
       "      <td>13.5</td>\n",
       "      <td>9.0</td>\n",
       "      <td>f85ce7f7b453dc3f365e</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>AGFA000000061588</td>\n",
       "      <td>bad4d3362073d53febf7</td>\n",
       "      <td>002</td>\n",
       "      <td>semi_solid</td>\n",
       "      <td>-76.3062</td>\n",
       "      <td>67.807</td>\n",
       "      <td>-95.5</td>\n",
       "      <td>5.0</td>\n",
       "      <td>abb5d56e4304e93f988a</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>AGFA000000061588</td>\n",
       "      <td>80ed1e7f09fdbe3fa4ce</td>\n",
       "      <td>002</td>\n",
       "      <td>solid</td>\n",
       "      <td>-63.3292</td>\n",
       "      <td>-70.842</td>\n",
       "      <td>-182.5</td>\n",
       "      <td>5.0</td>\n",
       "      <td>8e5a16dffa46e13fa8ca</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>AGFA000000061588</td>\n",
       "      <td>ebc6e342207fef3f80e0</td>\n",
       "      <td>002</td>\n",
       "      <td>semi_solid</td>\n",
       "      <td>-66.0612</td>\n",
       "      <td>-64.012</td>\n",
       "      <td>-183.5</td>\n",
       "      <td>4.0</td>\n",
       "      <td>1e0a3533cf7ae53febfc</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>AGFA000000061588</td>\n",
       "      <td>2404c48f6407de3fec72</td>\n",
       "      <td>005</td>\n",
       "      <td>semi_solid</td>\n",
       "      <td>106.7378</td>\n",
       "      <td>11.801</td>\n",
       "      <td>13.5</td>\n",
       "      <td>9.0</td>\n",
       "      <td>f85ce7f7b453dc3f365e</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           seriesid              NoduleID DoctorID  NoduleType    coordX  \\\n",
       "0  AGFA000000061588  3ccf38f4489fd23fe166      002       solid  105.3718   \n",
       "1  AGFA000000061588  bad4d3362073d53febf7      002  semi_solid  -76.3062   \n",
       "2  AGFA000000061588  80ed1e7f09fdbe3fa4ce      002       solid  -63.3292   \n",
       "3  AGFA000000061588  ebc6e342207fef3f80e0      002  semi_solid  -66.0612   \n",
       "4  AGFA000000061588  2404c48f6407de3fec72      005  semi_solid  106.7378   \n",
       "\n",
       "   coordY  coordZ  diameter_mm         GroupNoduleID  \n",
       "0  12.484    13.5          9.0  f85ce7f7b453dc3f365e  \n",
       "1  67.807   -95.5          5.0  abb5d56e4304e93f988a  \n",
       "2 -70.842  -182.5          5.0  8e5a16dffa46e13fa8ca  \n",
       "3 -64.012  -183.5          4.0  1e0a3533cf7ae53febfc  \n",
       "4  11.801    13.5          9.0  f85ce7f7b453dc3f365e  "
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nodules_with_group_index.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's plot number of nodules with different numbers of verifications for each doctor. Number of verifications represents number of overlapping nodules in group: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 504x360 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAmcAAAGtCAYAAABTKdNeAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzt3XuYXXV97/H31wRJMYFwkTRlwGBFCJdAkuGiUkiktkA9XCSCPFigTZujVdQjcgA9T9X2SLFYUatCU+EA6iHQFCqllgqSKcfIRSIJFxMlRZRBSiCFmLHEJvF7/tiLMJCEWTOzL7+w36/nmSd7/9baa3+yZmbnk3WNzESSJElleFWnA0iSJOkFljNJkqSCWM4kSZIKYjmTJEkqiOVMkiSpIJYzSZKkgljOJEmSCmI5kyRJKojlTJIkqSBjOx1gNHbbbbecMmVKU5b1i1/8gte85jVNWVazmKmeEjNBmbnMVI+Z6isxl5nqMVN9zcq1ZMmSpzPztUPOmJnb7NfMmTOzWRYtWtS0ZTWLmeopMVNmmbnMVI+Z6isxl5nqMVN9zcoF3Js1+o27NSVJkgpiOZMkSSqI5UySJKkg2/QJAZIkqfPWr19Pf38/69atG9VydtppJ5YvX96kVM0z3Fzjxo2jp6eH7bbbbkTvZzmTJEmj0t/fz4QJE5gyZQoRMeLlrF27lgkTJjQxWXMMJ1dmsnr1avr7+9l7771H9H7u1pQkSaOybt06dt1111EVs1eKiGDXXXcd1VZEy5kkSRo1i9kLRrsuLGeSJEkFsZxJkqSiHH/88Tz77LMAfOELX2Dq1KmcccYZ3HTTTVx88cUjWuZFF130oudvfvObR52zVTwhQJIkFSEz+dWvfsU3v/nNTWNf/vKXue222+jp6QHghBNOGNGyL7roIj760Y9uev7d7353dGFbyC1nkiSpqS644AK+9KUvbXr+iU98gs985jNccsklHHrooUybNo2Pf/zjADz66KPsu+++nHnmmRx++OE89thjTJkyhaeffpr3vOc9PPLIIxx33HFceumlXHXVVbz//e8H4Mknn+Tkk0/m4IMP5uCDD95Utk466SRmzpzJAQccwPz58zflee655zjkkEM444wzABg/fjzQKITnnXceBx54IAcddBDXXXcdAH19fcyaNYs5c+Ywc+ZMzjjjDBp3YGosb//992fatGl85CMfafr6c8uZJElqqtNOO40PfehDvO997wPg+uuv5/zzz2fx4sXcc889ZCYnnHACd9xxB3vttRcPP/wwV199NQcccMCLLllx+eWXc8stt7Bo0SJ22203rrrqqk3TPvCBD3D00Udz4403snHjRgYGBgC48sor2WWXXXjuuec49NBDOeWUU7j44ov54he/yNKlSzfLesMNN7B06VKWLVvG008/zaGHHspRRx0FwH333cdDDz3EhAkTOPbYY1m8eDFTp07lxhtvZMWKFUTEpt2vzeSWM0mS1FTTp09n1apV/OxnP2PZsmXsvPPOPPDAA3zrW99i+vTpzJgxgxUrVvDwww8D8LrXvY4jjjhiWO9x++238973vheAMWPGsNNOOwGNY9QOPvhgjjjiCB577LFN77E13/nOdzj99NMZM2YMkyZN4uijj+Z73/seAIcddhg9PT286lWv4pBDDuHRRx9lp512Yty4ccydO5cbbriBHXbYYbirZ0gtK2cRcWVErIqIB7cw7dyIyIjYrXoeEfGFiFgZEfdHxIxW5ZIkSa33zne+k4ULF3Lddddx2mmnkZlceOGFLF26lKVLl7Jy5Urmzp0LwGte85qmvGdfXx+33XYbd955J8uWLWP69Omjut7Y9ttvv+nxmDFj2LBhA2PHjuWee+5hzpw53HzzzRx77LHNiP4irdxydhWwWeKI2BP4HeCng4aPA/apvuYBl7UwlyRJarHTTjuNBQsWsHDhQt75znfyu7/7u1x55ZWbdj8+/vjjrFq1asTLP+aYY7jsskZd2LhxI2vWrGHNmjXsvPPO7LDDDqxYsYK77rpr0/zbbbcd69ev32w5v/Vbv8V1113Hxo0beeqpp7jjjjs47LDDtvq+AwMDrFmzhuOPP55LL72UZcuWjfjvsDUtO+YsM++IiClbmHQp8D+BbwwaOxG4JhtH2t0VERMjYnJmPtGqfJIkqXUOOOAA1q5dyx577MHkyZOZPHkyy5cv501vehPQOCD/a1/7GmPGjBnR8j//+c8zb948rrjiCsaMGcNll13Gsccey+WXX87UqVPZd999X7SrdN68eUybNo0ZM2bw9a9/fdP4ySefzJ133snBBx9MRPCXf/mX/Pqv/zorVqzY4vuuXbuWE088kXXr1pGZfPaznx1R/pcTz5950ApVObs5Mw+s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\n",
      "text/plain": [
       "<Figure size 720x504 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(7, 5))\n",
    "\n",
    "data = (\n",
    "    nodules_with_group_index\n",
    "    .set_index('GroupNoduleID')\n",
    "    .assign(verifications=lambda df: df.groupby(level=0).agg({'NoduleID': 'count'}))\n",
    "    .groupby(['DoctorID', 'verifications'])\n",
    "    .agg({'NoduleID': 'count'})\n",
    "    .query('verifications <= 3')\n",
    "    .reset_index()\n",
    ")\n",
    "\n",
    "plt.figure(figsize=(10, 7))\n",
    "sns.barplot(x='DoctorID', y='NoduleID', hue='verifications', data=data)\n",
    "plt.ylabel('Counts')\n",
    "plt.grid(True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Gluing overlapping nodules together"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Due to the fact that each cancer nodule can be annotated by several doctors we need to have a way to group overlapping nodules and then cover them with one big nodule. Generally, we also want to take into account different weights for different nodules. Function **glue_nodules** from **radio.annotation** will do this work for you. There are two conditions:\n",
    "nodules dataframe must have confidence column that reflects the weight of nodule and **proba** parameter that is required for building normal-density approximation of covering nodule."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "columns = ['SpacingZ', 'SpacingY', 'SpacingX', 'OriginZ', 'OriginY', 'OriginX']\n",
    "\n",
    "group_nodules = (\n",
    "    radio.annotation.read_nodules(annotation_path)\n",
    "    .merge(dataset_info[columns].reset_index(), on='seriesid', how='inner')\n",
    "    .assign(coordZ=lambda df: df.loc[:, 'coordZ'] * df.loc[df.index, 'SpacingZ'] + df.loc[df.index, 'OriginZ'],\n",
    "            coordY=lambda df: df.loc[:, 'coordY'] * df.loc[df.index, 'SpacingY'] + df.loc[df.index, 'OriginY'],\n",
    "            coordX=lambda df: df.loc[:, 'coordX'] * df.loc[df.index, 'SpacingX'] + df.loc[df.index, 'OriginX'])\n",
    "    .reset_index()\n",
    "    .assign(NoduleConfidence=1)\n",
    "    .drop(columns, axis=1)\n",
    "    .pipe(radio.annotation.get_nodules_groups, proba=0.8)\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>GroupNoduleID</th>\n",
       "      <th>NoduleConfidence</th>\n",
       "      <th>coordX</th>\n",
       "      <th>coordY</th>\n",
       "      <th>coordZ</th>\n",
       "      <th>diameter_mm</th>\n",
       "      <th>seriesid</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0007ea831b5ca23f7477</td>\n",
       "      <td>1.0</td>\n",
       "      <td>-27.7905</td>\n",
       "      <td>-60.732</td>\n",
       "      <td>-312.799900</td>\n",
       "      <td>5.000000</td>\n",
       "      <td>AGFA000000069251</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>005faa5f0433bf3f96e7</td>\n",
       "      <td>1.0</td>\n",
       "      <td>92.8902</td>\n",
       "      <td>-66.632</td>\n",
       "      <td>-424.799900</td>\n",
       "      <td>9.000000</td>\n",
       "      <td>AGFA000000061613</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>006285c4dd09a43f608f</td>\n",
       "      <td>1.0</td>\n",
       "      <td>150.8728</td>\n",
       "      <td>-87.954</td>\n",
       "      <td>-398.799900</td>\n",
       "      <td>4.000000</td>\n",
       "      <td>AGFA000000066044</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>006cffaa38d1e03f7755</td>\n",
       "      <td>1.0</td>\n",
       "      <td>94.3617</td>\n",
       "      <td>25.733</td>\n",
       "      <td>-395.800000</td>\n",
       "      <td>5.000000</td>\n",
       "      <td>AGFA000000073050</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>007a7a5e373cdb3ffc6d</td>\n",
       "      <td>1.0</td>\n",
       "      <td>100.4837</td>\n",
       "      <td>10.947</td>\n",
       "      <td>-450.466567</td>\n",
       "      <td>4.400565</td>\n",
       "      <td>AGFA000000065450</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          GroupNoduleID  NoduleConfidence    coordX  coordY      coordZ  \\\n",
       "0  0007ea831b5ca23f7477               1.0  -27.7905 -60.732 -312.799900   \n",
       "1  005faa5f0433bf3f96e7               1.0   92.8902 -66.632 -424.799900   \n",
       "2  006285c4dd09a43f608f               1.0  150.8728 -87.954 -398.799900   \n",
       "3  006cffaa38d1e03f7755               1.0   94.3617  25.733 -395.800000   \n",
       "4  007a7a5e373cdb3ffc6d               1.0  100.4837  10.947 -450.466567   \n",
       "\n",
       "   diameter_mm          seriesid  \n",
       "0     5.000000  AGFA000000069251  \n",
       "1     9.000000  AGFA000000061613  \n",
       "2     4.000000  AGFA000000066044  \n",
       "3     5.000000  AGFA000000073050  \n",
       "4     4.400565  AGFA000000065450  "
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "group_nodules.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Source annotation contained more nodules then dataframe with glued nodules:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(678, 453)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nodules.shape[0], group_nodules.shape[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Number of nodules reduced because we united overlapping nodules within the group into one nodule."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Computing doctors and nodules confidences"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 8/8 [00:14<00:00,  1.80s/it]\n"
     ]
    }
   ],
   "source": [
    "from radio.annotation import get_doctors_confidences\n",
    "from radio.annotation import compute_nodule_confidence\n",
    "\n",
    "nodules_with_confidences = (\n",
    "    radio.annotation.read_nodules(annotation_path)\n",
    "    .merge(dataset_info[columns].reset_index(), on='seriesid', how='inner')\n",
    "    .assign(coordZ=lambda df: df.loc[:, 'coordZ'] * df.loc[df.index, 'SpacingZ'] + df.loc[df.index, 'OriginZ'],\n",
    "            coordY=lambda df: df.loc[:, 'coordY'] * df.loc[df.index, 'SpacingY'] + df.loc[df.index, 'OriginY'],\n",
    "            coordX=lambda df: df.loc[:, 'coordX'] * df.loc[df.index, 'SpacingX'] + df.loc[df.index, 'OriginX'])\n",
    "    .reset_index()\n",
    "    .pipe(get_doctors_confidences, smooth=4, n_iters=8)\n",
    "    .pipe(compute_nodule_confidence, alpha=0.5, weight_by_doctor=False)\n",
    "    .pipe(radio.annotation.get_nodules_groups, proba=0.8)\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's have a look at distribution of nodules' confidence after min-max scaling:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.5/dist-packages/matplotlib/axes/_axes.py:6462: UserWarning: The 'normed' kwarg is deprecated, and has been replaced by the 'density' kwarg.\n",
      "  warnings.warn(\"The 'normed' kwarg is deprecated, and has been \"\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f982e365ba8>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import seaborn as sns\n",
    "\n",
    "x = nodules_with_confidences.NoduleConfidence\n",
    "nodules_with_confidences.NoduleConfidence = (x - x.min()) / (x.max() - x.min())\n",
    "\n",
    "sns.distplot(nodules_with_confidences.loc[:, 'NoduleConfidence'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating dicom dataset's FilesIndex and Dataset objects"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "from radio import dataset as ds\n",
    "from radio.dataset import V, B, F\n",
    "\n",
    "ct_index = ds.FilesIndex(dataset_info.index.values, paths=dict(dataset_info.loc[:, 'ScanPath']), dirs=True)\n",
    "ct_dataset = ds.Dataset(ct_index, batch_class=radio.CTImagesMaskedBatch)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Remember that input dataframe for **fetch_nodules_info** actions requires *seriesuid* column:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>DoctorID</th>\n",
       "      <th>NoduleID</th>\n",
       "      <th>NoduleType</th>\n",
       "      <th>coordX</th>\n",
       "      <th>coordY</th>\n",
       "      <th>coordZ</th>\n",
       "      <th>diameter_mm</th>\n",
       "      <th>seriesid</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>40</th>\n",
       "      <td>002</td>\n",
       "      <td>daba26a08d02e63f40b9</td>\n",
       "      <td>solid</td>\n",
       "      <td>410.0</td>\n",
       "      <td>274.0</td>\n",
       "      <td>330.0</td>\n",
       "      <td>9.0</td>\n",
       "      <td>AGFA000000061588</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>41</th>\n",
       "      <td>002</td>\n",
       "      <td>201b5020bd419f3f1621</td>\n",
       "      <td>semi_solid</td>\n",
       "      <td>144.0</td>\n",
       "      <td>355.0</td>\n",
       "      <td>221.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>AGFA000000061588</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>45</th>\n",
       "      <td>002</td>\n",
       "      <td>763e221589d0e83f508c</td>\n",
       "      <td>solid</td>\n",
       "      <td>163.0</td>\n",
       "      <td>152.0</td>\n",
       "      <td>134.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>AGFA000000061588</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>46</th>\n",
       "      <td>002</td>\n",
       "      <td>31dd3fbde194ed3f0cee</td>\n",
       "      <td>semi_solid</td>\n",
       "      <td>159.0</td>\n",
       "      <td>162.0</td>\n",
       "      <td>133.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>AGFA000000061588</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>80</th>\n",
       "      <td>005</td>\n",
       "      <td>60ebbefda8cbe33fb8e9</td>\n",
       "      <td>semi_solid</td>\n",
       "      <td>412.0</td>\n",
       "      <td>273.0</td>\n",
       "      <td>330.0</td>\n",
       "      <td>9.0</td>\n",
       "      <td>AGFA000000061588</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   DoctorID              NoduleID  NoduleType  coordX  coordY  coordZ  \\\n",
       "40      002  daba26a08d02e63f40b9       solid   410.0   274.0   330.0   \n",
       "41      002  201b5020bd419f3f1621  semi_solid   144.0   355.0   221.0   \n",
       "45      002  763e221589d0e83f508c       solid   163.0   152.0   134.0   \n",
       "46      002  31dd3fbde194ed3f0cee  semi_solid   159.0   162.0   133.0   \n",
       "80      005  60ebbefda8cbe33fb8e9  semi_solid   412.0   273.0   330.0   \n",
       "\n",
       "    diameter_mm          seriesid  \n",
       "40          9.0  AGFA000000061588  \n",
       "41          5.0  AGFA000000061588  \n",
       "45          5.0  AGFA000000061588  \n",
       "46          4.0  AGFA000000061588  \n",
       "80          9.0  AGFA000000061588  "
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ct_nodules = (\n",
    "    radio.annotation.read_nodules(annotation_path)\n",
    ")\n",
    "ct_nodules.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There is one major problem connected with annotation provided by radiologists: coordinates of nodules' centers are provided in pixel scale while diameter has 'mm' scale. If we simply put nodules as an argument of **fetch_nodules_info** function, we will get wrong masks. This could be avoided if both nodules' centers coordinates and diameter were provided in 'mm' scale. However in that case we would need to transform nodules dataframe using info about spacing and origin from all dataset. It is very expensive operation because fetching origin for all scans in dataset will require to read all CT scans in RAM. Fortunatelly, there is an alternative solution: transform coords 'on-the-fly' using F-named expression from dataset submodule in a combination with inverse transform using spacing and origin from batch:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "def inverse_spacing_origin_transform(batch, nodules):\n",
    "    \"\"\" Transform spacing and origin in nodules dataframe on fly. \"\"\"\n",
    "    indices = np.intersect1d(nodules.seriesuid.values, batch.indices)\n",
    "\n",
    "    nodules = nodules.set_index('seriesuid')\n",
    "    if len(indices) > 0:\n",
    "        nodules = nodules.loc[indices, :]\n",
    "        pos = batch.index.get_pos(nodules.index)\n",
    "\n",
    "        nodules.loc[:, 'coordZ'] *= batch.spacing[pos, 0]\n",
    "        nodules.loc[:, 'coordY'] *= batch.spacing[pos, 1]\n",
    "        nodules.loc[:, 'coordX'] *= batch.spacing[pos, 2]\n",
    "\n",
    "        nodules.loc[:, 'coordZ'] += batch.origin[pos, 0]\n",
    "        nodules.loc[:, 'coordY'] += batch.origin[pos, 1]\n",
    "        nodules.loc[:, 'coordX'] += batch.origin[pos, 2]\n",
    "\n",
    "    return nodules.reset_index()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "sample_nodules_ppl = ct_dataset >> (\n",
    "    ds.Pipeline()\n",
    "    .load(fmt='blosc', components=['images', 'spacing', 'origin'])\n",
    "    .fetch_nodules_info(nodules=F(inverse_spacing_origin_transform, nodules=ct_nodules))\n",
    "    .unify_spacing(shape=(400, 512, 512), spacing=(1.7, 1.0, 1.0), method='pil-simd')\n",
    "    .normalize_hu()\n",
    "    .create_mask()\n",
    "    .sample_nodules(nodule_size=(32, 64, 64), batch_size=None, share=1.0)\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If we want to use **group_nodules** dataframe that was created earlier, we don't need to transform coordinates using inverse spacing transform: we have already done this before computation of overlapping groups. In that case only inverse origin transform must be applied. As an alternative to this we can just set origin to zeros after loading scans:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "sample_nodules_ppl = ct_dataset >> (\n",
    "    ds.Pipeline()\n",
    "    .load(fmt='blosc', components=['images', 'spacing', 'origin'])\n",
    "    .fetch_nodules_info(nodules=group_nodules.assign(seriesuid=lambda df: df.loc[:, 'seriesid']))\n",
    "    .normalize_hu()\n",
    "    .create_mask()\n",
    "    .sample_nodules(nodule_size=(32, 64, 64), batch_size=None, share=1.0)\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's generate batch with crops sampled from two scans:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "batch = sample_nodules_ppl.next_batch(batch_size=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can plot obtained nodules and visually verify built masks:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7f982e2fe198>"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x576 with 3 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10, 8))\n",
    "\n",
    "image, mask = batch.get(2, 'images'), batch.get(2, 'masks')\n",
    "\n",
    "ax_image = plt.subplot('131')\n",
    "ax_image.imshow(image[16, :, :])\n",
    "\n",
    "ax_mask = plt.subplot('132')\n",
    "ax_mask.imshow(mask[16, :, :])\n",
    "\n",
    "ax_mask_image = plt.subplot('133')\n",
    "ax_mask_image.imshow(mask[16, :, :] * image[16, :, :])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.6+"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
